[][src]Crate option_lock

This crate defines a locking structure wrapping an Option value. The lock can be acquired for either an exclusive write lock or a series of read locks, using a single atomic operation per acquisition.

The try_lock, try_read, and try_take operations are non-blocking and appropriate for using within a polled Future, but the lock cannot register wakers or park the current thread.

This structure allows for multiple usage patterns. As one example, it can be used to implement a version of once_cell / lazy_static:

use option_lock::{OptionLock, OptionGuard, OptionRead, ReadError};
use std::collections::HashMap;

static REPOSITORY: OptionLock<HashMap<String, u32>> = OptionLock::new();

pub fn resource_map() -> OptionRead<'static, HashMap<String, u32>> {
  loop {
    match REPOSITORY.try_read() {
      Ok(read) => break read,
      Err(ReadError::Empty) => {
        if let Ok(mut guard) = REPOSITORY.try_lock() {
          let mut inst = HashMap::new();
          inst.insert("hello".to_string(), 5);
          guard.replace(inst);
          break OptionGuard::downgrade(guard).unwrap();
        }
      }
      Err(_) => {}
    }
    // wait while the resource is created
    std::thread::yield_now();
  }
}

assert_eq!(*resource_map().get("hello").unwrap(), 5);

There are additional examples in the repository.

This crate is no-std compatible when compiled without the std feature.

Structs

OptionGuard

A write guard for the value of an OptionLock

OptionLock

A read-write lock around an Option value

OptionRead

A read guard for the value of a populated OptionLock

TryLockError

An error which may be thrown by OptionLock::try_lock

Enums

ReadError

An error which may be thrown by [OptionLock::read]

Status

The result of OptionLock::status